"""辩论式法律思维训练服务"""
from typing import Dict, Any, List, Optional
from datetime import datetime
import uuid
import json
from app.ai.llm_service import get_llm_service
from app.ai.legalbert_service import get_legalbert_service
from app.core.database import RedisClient


class DebateService:
    """辩论式法律思维训练服务"""
    
    def __init__(self):
        try:
            self.redis = RedisClient.get_client()
        except:
            self.redis = None
        self.llm_service = get_llm_service()
        self.legalbert = get_legalbert_service()
    
    async def start_debate(
        self,
        user_id: str,
        question_id: str,
        question_content: str,
        user_position: str = "中立",
        question_options: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        开始辩论
        
        Args:
            user_id: 用户ID
            question_id: 题目ID
            question_content: 题目内容
            user_position: 用户立场（支持/反对/中立）
            question_options: 题目选项（可选）
            
        Returns:
            辩论会话信息
        """
        debate_id = f"debate_{uuid.uuid4().hex[:8]}"
        
        # 检测用户水平（用于调整引导方式）
        user_level = self._detect_user_level(user_id)
        
        debate_session = {
            "debate_id": debate_id,
            "user_id": user_id,
            "question_id": question_id,
            "question_content": question_content,
            "question_options": question_options or [],
            "user_position": user_position,
            "status": "active",
            "rounds": [],
            "started_at": datetime.now().isoformat(),
            "current_round": 0,
            "user_level": user_level  # 添加用户水平信息
        }
        
        # 保存到Redis
        if self.redis:
            try:
                key = f"debate:{debate_id}"
                self.redis.setex(
                    key,
                    86400 * 7,  # 保存7天
                    json.dumps(debate_session, ensure_ascii=False)
                )
            except Exception as e:
                print(f"保存辩论会话失败: {e}")
        
        return debate_session
    
    async def submit_argument(
        self,
        debate_id: str,
        user_argument: str,
        round_number: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        提交用户论点
        
        Args:
            debate_id: 辩论ID
            user_argument: 用户论点
            round_number: 轮次（可选，自动递增）
            
        Returns:
            提交结果和AI回应
        """
        # 获取辩论会话
        debate_session = await self._get_debate_session(debate_id)
        if not debate_session:
            raise ValueError(f"辩论会话不存在: {debate_id}")
        
        if debate_session["status"] != "active":
            raise ValueError("辩论已结束")
        
        # 确定轮次
        if round_number is None:
            round_number = debate_session.get("current_round", 0) + 1
        
        # 使用Legal-BERT分析用户论点
        argument_analysis = await self._analyze_argument(user_argument, debate_session["question_content"])
        
        # 生成AI回应（添加超时控制，给大模型充足时间）
        import asyncio
        try:
            ai_response = await asyncio.wait_for(
                self._generate_ai_response(
                    debate_session,
                    user_argument,
                    round_number,
                    argument_analysis
                ),
                timeout=60.0  # 60秒超时，给大模型充足时间
            )
        except asyncio.TimeoutError:
            print("生成AI回应超时（60秒），使用默认回应")
            ai_response = {
                "response_text": "抱歉，AI回应生成超时，请稍后重试或继续下一轮辩论。",
                "role": "对手",
                "error": "timeout"
            }
        
        # 更新辩论会话
        round_data = {
            "round": round_number,
            "user_argument": user_argument,
            "ai_response": ai_response["response_text"],
            "ai_role": ai_response.get("role", "对手"),
            "argument_analysis": argument_analysis,
            "timestamp": datetime.now().isoformat()
        }
        
        debate_session["rounds"].append(round_data)
        debate_session["current_round"] = round_number
        
        # 判断是否结束辩论（达到最大轮次或用户明确结束）
        max_rounds = 5
        if round_number >= max_rounds:
            debate_session["status"] = "ended"
            # 生成最终评估
            debate_session["evaluation"] = await self._evaluate_debate(debate_session)
        
        # 保存更新
        await self._save_debate_session(debate_id, debate_session)
        
        return {
            "debate_id": debate_id,
            "round": round_number,
            "user_argument": user_argument,
            "ai_response": ai_response,
            "argument_analysis": argument_analysis,
            "debate_status": debate_session["status"],
            "is_final_round": round_number >= max_rounds
        }
    
    async def get_ai_response(
        self,
        debate_id: str,
        user_argument: str
    ) -> Dict[str, Any]:
        """
        获取AI回应（单独调用，不更新轮次）
        
        Args:
            debate_id: 辩论ID
            user_argument: 用户论点
            
        Returns:
            AI回应
        """
        debate_session = await self._get_debate_session(debate_id)
        if not debate_session:
            raise ValueError(f"辩论会话不存在: {debate_id}")
        
        # 分析论点
        argument_analysis = await self._analyze_argument(
            user_argument,
            debate_session["question_content"]
        )
        
        # 生成AI回应（添加超时控制）
        import asyncio
        current_round = len(debate_session.get("rounds", []))
        try:
            ai_response = await asyncio.wait_for(
                self._generate_ai_response(
                    debate_session,
                    user_argument,
                    current_round + 1,
                    argument_analysis
                ),
                timeout=60.0  # 60秒超时
            )
        except asyncio.TimeoutError:
            print("生成AI回应超时（60秒），使用默认回应")
            ai_response = {
                "response_text": "抱歉，AI回应生成超时，请稍后重试。",
                "role": "对手",
                "error": "timeout"
            }
        
        return ai_response
    
    async def evaluate_debate(self, debate_id: str) -> Dict[str, Any]:
        """
        评估辩论质量
        
        Args:
            debate_id: 辩论ID
            
        Returns:
            评估结果
        """
        debate_session = await self._get_debate_session(debate_id)
        if not debate_session:
            raise ValueError(f"辩论会话不存在: {debate_id}")
        
        evaluation = await self._evaluate_debate(debate_session)
        
        # 更新会话
        debate_session["evaluation"] = evaluation
        debate_session["status"] = "ended"
        await self._save_debate_session(debate_id, debate_session)
        
        return evaluation
    
    async def end_debate(self, debate_id: str) -> Dict[str, Any]:
        """
        结束辩论
        
        Args:
            debate_id: 辩论ID
            
        Returns:
            最终评估结果
        """
        debate_session = await self._get_debate_session(debate_id)
        if not debate_session:
            raise ValueError(f"辩论会话不存在: {debate_id}")
        
        # 生成评估
        evaluation = await self._evaluate_debate(debate_session)
        
        # 更新会话
        debate_session["evaluation"] = evaluation
        debate_session["status"] = "ended"
        debate_session["ended_at"] = datetime.now().isoformat()
        await self._save_debate_session(debate_id, debate_session)
        
        return {
            "debate_id": debate_id,
            "status": "ended",
            "evaluation": evaluation,
            "total_rounds": len(debate_session.get("rounds", []))
        }
    
    # 辅助方法
    
    async def _analyze_argument(
        self,
        argument: str,
        question_content: str
    ) -> Dict[str, Any]:
        """分析用户论点"""
        # 使用Legal-BERT提取关键信息
        key_facts = await self.legalbert.extract_key_facts(argument)
        entities = await self.legalbert.extract_entities(argument)
        
        # 分析推理链条
        reasoning_chain = await self.legalbert.extract_legal_reasoning_chain(
            question_content,
            argument
        )
        
        return {
            "key_facts": key_facts,
            "legal_entities": entities,
            "reasoning_chain": reasoning_chain,
            "argument_length": len(argument),
            "has_legal_provisions": len([e for e in entities if e["type"] == "法律条文"]) > 0
        }
    
    def _identify_legal_domain(self, question_content: str, question_options: List[str] = None, user_argument: str = None) -> Dict[str, str]:
        """
        识别题目的法律领域（同时考虑题目内容和用户论点）
        
        Args:
            question_content: 题目内容
            question_options: 题目选项（可选）
            user_argument: 用户论点（可选，用于更准确识别法律领域）
            
        Returns:
            包含法律领域信息的字典
        """
        content_lower = question_content.lower()
        all_text = question_content
        if question_options:
            all_text += " " + " ".join(question_options)
        # 如果提供了用户论点，也加入分析
        if user_argument:
            all_text += " " + user_argument
        all_text_lower = all_text.lower()
        
        # 行政法相关关键词（新增）
        administrative_keywords = ["行政行为", "具体行政行为", "抽象行政行为", "行政赔偿", "行政补偿", 
                                 "行政确认", "行政许可", "行政处罚", "行政强制", "行政复议", "行政诉讼",
                                 "行政主体", "行政机关", "行政相对人", "行政责任", "行政程序", "行政决定",
                                 "行政无效", "行政撤销", "行政违法", "行政不作为", "行政作为"]
        
        # 婚姻家庭法/婚姻财产相关关键词
        marriage_keywords = ["夫妻", "婚姻", "财产分割", "共同财产", "婚前", "婚后", "离婚", "配偶", 
                            "夫妻共同", "夫妻财产", "婚姻关系", "家庭财产", "夫妻债务", "财产利益"]
        
        # 合同法相关关键词
        contract_keywords = ["合同", "买卖", "租赁", "协议", "约定", "缔约", "履行", "违约", 
                            "意思表示", "合同成立", "合同生效", "合同履行"]
        
        # 侵权法相关关键词
        tort_keywords = ["侵权", "损害", "赔偿", "过错", "责任", "伤害", "损失"]
        
        # 物权法相关关键词
        property_keywords = ["物权", "所有权", "占有", "使用", "收益", "处分", "不动产", "动产"]
        
        # 判断法律领域（优先考虑行政法，因为行政法关键词更具体）
        administrative_count = sum(1 for keyword in administrative_keywords if keyword in all_text_lower)
        marriage_count = sum(1 for keyword in marriage_keywords if keyword in all_text_lower)
        contract_count = sum(1 for keyword in contract_keywords if keyword in all_text_lower)
        tort_count = sum(1 for keyword in tort_keywords if keyword in all_text_lower)
        property_count = sum(1 for keyword in property_keywords if keyword in all_text_lower)
        
        # 根据关键词数量判断主要法律领域（行政法优先）
        if administrative_count > 0:
            domain = "行政法"
            description = f"这是一道关于**行政法**的题目。题目涉及行政行为、行政赔偿、行政确认等行政法相关内容。你必须基于《行政诉讼法》、《国家赔偿法》、《行政处罚法》等行政法相关规定来分析和回应，不要使用民法、合同法等其他法律领域的知识。"
        elif marriage_count > 0 and marriage_count >= contract_count:
            domain = "婚姻家庭法/婚姻财产"
            description = f"这是一道关于**婚姻家庭法/婚姻财产**的题目。题目涉及夫妻共同财产、财产分割等婚姻家庭法相关内容。你必须基于《民法典》婚姻家庭编的相关规定来分析和回应，不要使用合同法的知识。"
        elif contract_count > 0:
            domain = "合同法"
            description = f"这是一道关于**合同法**的题目。题目涉及合同成立、履行、违约等合同法相关内容。你必须基于《民法典》合同编的相关规定来分析和回应。"
        elif tort_count > 0:
            domain = "侵权责任法"
            description = f"这是一道关于**侵权责任法**的题目。题目涉及侵权责任、损害赔偿等内容。你必须基于《民法典》侵权责任编的相关规定来分析和回应。"
        elif property_count > 0:
            domain = "物权法"
            description = f"这是一道关于**物权法**的题目。题目涉及物权、所有权等内容。你必须基于《民法典》物权编的相关规定来分析和回应。"
        else:
            domain = "综合/其他"
            description = "这是一道综合性的法律题目。请根据题目的具体内容和用户论点，识别相关的法律领域，并基于相应的法律知识来分析和回应。"
        
        return {
            "domain": domain,
            "description": description
        }
    
    async def _generate_ai_response(
        self,
        debate_session: Dict[str, Any],
        user_argument: str,
        round_number: int,
        argument_analysis: Dict[str, Any]
    ) -> Dict[str, Any]:
        """生成AI回应（增强版：展示思考过程，更有说服力，根据用户水平调整引导）"""
        question_content = debate_session["question_content"]
        question_options = debate_session.get("question_options", [])
        user_position = debate_session.get("user_position", "中立")
        previous_rounds = debate_session.get("rounds", [])
        user_level = debate_session.get("user_level", "beginner")  # 获取用户水平
        
        # 根据轮次和用户立场确定AI角色
        if round_number == 1:
            # 第一轮：AI作为对手，提出质疑
            ai_role = "对手"
            role_description = "作为法律辩论的对手，提出质疑和反驳"
        elif round_number <= 3:
            # 中间轮次：深入探讨
            ai_role = "对手"
            role_description = "继续深入探讨，指出论证中的薄弱环节"
        else:
            # 后期：法官角色，评估论证
            ai_role = "法官"
            role_description = "作为法官，评估论证的完整性和逻辑性"
        
        # 提取关键信息
        key_facts = argument_analysis.get('key_facts', [])
        legal_entities = argument_analysis.get('legal_entities', [])
        reasoning_chain = argument_analysis.get('reasoning_chain', {})
        
        # 识别题目的法律领域（同时考虑用户论点，因为用户论点可能包含更明确的法律领域信息）
        legal_domain = self._identify_legal_domain(question_content, question_options, user_argument)
        
        # 构建详细的提示词
        prompt = f"""
你是一位经验丰富的{role_description}，正在与学员进行法律辩论训练。

**⚠️ 重要：你必须基于题目的具体法律领域进行回应，不要使用不相关的法律领域！**

【题目内容】
{question_content}

【题目的法律领域】
{legal_domain['description']}

**关键要求：**
- 这道题目涉及的是：{legal_domain['domain']}
- 你必须基于{legal_domain['domain']}相关的法律知识来回应
- **绝对禁止**使用不相关的法律领域（如：如果题目是婚姻财产，不要用合同法的知识；如果题目是合同，不要用婚姻法的知识）
- 如果题目涉及"夫妻"、"婚姻"、"财产分割"等关键词，这是**婚姻家庭法/婚姻财产**相关题目
- 如果题目涉及"合同"、"买卖"、"租赁"等关键词，这是**合同法**相关题目
- 必须严格区分不同法律领域，不要混淆

"""
        
        # 添加题目选项（如果有）
        if question_options:
            prompt += "【题目选项】\n"
            for i, option in enumerate(question_options, 1):
                prompt += f"{option}\n"
            prompt += "\n"
        
        prompt += f"""
【学员立场】
{user_position}

【学员的论点】（第{round_number}轮）
{user_argument}

**⚠️ 关键提醒：**
- 学员的论点中明确提到了："{user_argument}"
- 你必须**直接针对学员论点的具体内容**进行回应
- 如果学员论点中提到了具体的法律概念（如"具体行政行为"、"行政赔偿"等），你必须基于这些概念所属的法律领域来回应
- **绝对禁止**忽略学员论点的具体内容，使用不相关的法律领域知识
- 如果学员问的是行政法问题，你必须用行政法知识回答，不能用合同法、民法等其他法律领域的知识

【论点深度分析】
- 关键事实提取：{len(key_facts)} 个
  {self._format_key_facts(key_facts[:5]) if key_facts else '  未提取到关键事实'}
- 法律实体识别：{len(legal_entities)} 个
  {self._format_legal_entities(legal_entities[:5]) if legal_entities else '  未识别到法律实体'}
- 推理链条完整性：{reasoning_chain.get('reasoning_completeness', {}).get('level', '未知')}
  {self._format_reasoning_chain(reasoning_chain) if reasoning_chain else '  推理链条不完整'}

"""
        
        # 添加历史对话（完整内容，不截断）
        if previous_rounds:
            prompt += "\n【之前的辩论历史】\n"
            for round_data in previous_rounds[-3:]:  # 取最近3轮，完整内容
                prompt += f"\n第{round_data['round']}轮：\n"
                prompt += f"学员论点：{round_data['user_argument']}\n"
                prompt += f"AI回应：{round_data['ai_response']}\n"
            prompt += "\n"
        
        if ai_role == "对手":
            # 根据用户水平调整引导方式
            if user_level == "beginner":
                # 初学者：从事实和逻辑开始，逐步引导
                prompt += f"""
【你的任务 - 初学者友好模式】
作为法律辩论的对手，你需要用温和、引导的方式帮助初学者。

**⚠️ 严格禁止使用模板回复！必须基于学员的具体论点进行回应！**

学员刚才说的具体内容是：
"{user_argument}"

**你必须做到：**
1. **直接引用学员的原话**：比如学员说"意思一致就成立合同"，你要说"你提到'意思一致就成立合同'，这个想法很有道理..."
2. **针对学员的具体问题回应**：如果学员问"当下的约定就成立么"，你要说"你问'当下的约定就成立么'，这是个很好的问题，让我们一起来思考..."
3. **绝对禁止使用以下模板回复**：
   ❌ "这是一个典型的合同纠纷案例，涉及违约责任的认定。"
   ❌ "请从法律条文、关键事实、逻辑推理三个角度深入分析这个问题。"
   ❌ 任何不针对学员具体论点的通用回复

**正确的回应方式示例：**
如果学员说："我按照非法学逻辑来思考,如果意思一致就成立合同,当下的约定就成立么"

你应该这样回应：
"我理解你的想法。你提到'意思一致就成立合同'，这个逻辑确实有道理。意思一致确实是合同成立的重要条件。

但你问'当下的约定就成立么'，这是个很好的问题。让我们一起来思考：除了意思一致，合同成立还需要什么条件呢？

比如，我们生活中约定'明天一起吃饭'，这是意思一致，但这是合同吗？可能不算。那什么情况下约定才算合同呢？我们可以从这些角度思考：
1. 双方是否真的达成了明确的约定？
2. 这个约定是否具有法律约束力？
3. 是否还需要其他条件（比如形式要求）？

你觉得呢？"

**回应要求：**

1. **必须引用学员的原话**：在回应中明确提到学员说了什么，比如"你提到..."、"你问..."、"你说..."

2. **针对学员的具体观点进行引导**：
   - 如果学员说"意思一致就成立合同"，你要说："你提到'意思一致就成立合同'，这个想法很有道理。意思一致确实是合同成立的重要条件。但我们可以想想，除了意思一致，还需要什么条件呢？"
   - 如果学员问"当下的约定就成立么"，你要说："你问'当下的约定就成立么'，这是个很好的问题。让我们一起来思考..."

3. **用生活化的例子引导**：不要直接说法律条文，而是用生活中的例子帮助理解

4. **根据轮次调整引导深度**：
   - 第1-2轮：重点关注事实和逻辑，用"你觉得..."、"我们可以这样想..."
   - 第3轮及以后：可以逐步引入法律概念，但要用通俗语言解释

**回应格式（必须包含）：**

【我理解你的观点】
（必须引用学员的原话，比如："你提到'意思一致就成立合同'，这个想法很有道理..."）

【让我们一起来思考】
（针对学员的具体问题，用引导性语言，比如："你问'当下的约定就成立么'，让我们想想..."）

【我的引导性问题】
（提出1-2个引导性问题，帮助学员深入思考，比如："你觉得除了意思一致，还需要什么条件呢？"）

**再次强调：**
- ❌ 绝对禁止使用"这是一个典型的合同纠纷案例"这类模板回复
- ❌ 绝对禁止使用"请从法律条文、关键事实、逻辑推理三个角度分析"这类通用指导
- ❌ **绝对禁止使用不相关的法律领域**：如果题目是婚姻财产，不要用合同法的知识；如果题目是合同，不要用婚姻法的知识
- ✅ 必须基于学员的具体论点，引用学员的原话，进行引导性回应
- ✅ 必须基于题目的法律领域（{legal_domain['domain']}）来引导，不要偏离主题
- ✅ 用生活化的例子和引导性问题帮助学员思考

请现在基于学员的具体论点："{user_argument}"，以及题目的法律领域（{legal_domain['domain']}），给出引导性回应。回应要详细、有针对性，至少200字。
"""
            else:
                # 进阶者：可以直接要求引用法条
                prompt += f"""
【你的任务】
作为法律辩论的对手，你需要：

**⚠️ 重要：你必须基于题目的法律领域（{legal_domain['domain']}）来回应，不要使用不相关的法律领域！**

1. **展示思考过程**：
   - 首先分析学员论点的核心观点是什么
   - 识别论点中的关键法律概念和事实
   - 评估论点的逻辑结构是否完整
   - **必须基于{legal_domain['domain']}相关的法律知识来分析**

2. **提出有说服力的质疑**：
   - 质疑学员论证中的逻辑漏洞（如果有）
   - 指出法律条文的适用是否准确，引用具体法条（**必须是{legal_domain['domain']}相关的法条**）
   - 提出反例或特殊情况，说明为什么学员的观点可能不成立
   - **不要使用不相关的法律领域**（如：如果题目是婚姻财产，不要用合同法的知识）
   - 要求学员进一步论证某个薄弱环节

3. **回应格式要求**：
   请按照以下格式组织你的回应：
   
   【我的思考】
   首先，让我分析一下你的论点...
   （展示你的思考过程，分析学员论点的核心观点、逻辑结构等）
   
   【我的质疑】
   但是，我认为你的论证存在以下问题：
   1. （具体问题1，引用相关法条或案例）
   2. （具体问题2，提出反例或特殊情况）
   3. （具体问题3，要求进一步论证）
   
   【我的建议】
   建议你从以下角度完善论证：
   - （建议1）
   - （建议2）

请以专业但友好的方式回应，帮助学员完善论证。回应要详细、有说服力，至少200字。
"""
        else:
            prompt += """
【你的任务】
作为法官，你需要：

1. **展示评估思考过程**：
   - 回顾整个辩论过程
   - 分析学员论证的演进过程
   - 评估论证的完整性和逻辑性

2. **全面评估**：
   - 论证的逻辑严谨性（是否使用了三段论、要件分析等）
   - 法律条文的适用准确性（引用的法条是否正确、适用是否恰当）
   - 论证的完整性（是否包含大前提、小前提、结论）
   - 需要改进的地方（具体指出哪些方面需要加强）

3. **回应格式要求**：
   请按照以下格式组织你的回应：
   
   【我的评估思考】
   让我回顾一下整个辩论过程...
   （展示你的评估思考过程）
   
   【论证质量评估】
   1. 逻辑严谨性：（评分和详细分析）
   2. 法律适用准确性：（评分和详细分析）
   3. 论证完整性：（评分和详细分析）
   
   【改进建议】
   建议从以下方面改进：
   - （具体建议1）
   - （具体建议2）

请以专业、客观的方式回应，帮助学员提升法律思维。回应要详细、有说服力，至少300字。
"""
        
        try:
            # 调用LLM生成回应（使用generate_text方法，直接传递完整prompt）
            # 优先使用generate_text，如果没有则使用analyze_legal_case
            if hasattr(self.llm_service, 'generate_text'):
                response_text = await self.llm_service.generate_text(
                    prompt,
                    max_tokens=800,
                    temperature=0.7
                )
            else:
                # 回退到analyze_legal_case
                response = await self.llm_service.analyze_legal_case(prompt)
                if isinstance(response, str):
                    response_text = response
                elif isinstance(response, dict):
                    response_text = response.get("analysis", "")
                    # 如果返回的是模板回复，尝试从其他字段获取
                    if "这是一个典型的" in response_text or len(response_text) < 50:
                        # 尝试从recommendation或其他字段获取
                        response_text = response.get("recommendation", response_text)
                        if len(response_text) < 50:
                            response_text = "请继续深入思考这个问题。"
                else:
                    response_text = "请继续完善你的论证。"
            
            # 确保回应有足够的长度和内容，且不是模板回复
            if len(response_text) < 100 or "这是一个典型的" in response_text:
                # 如果回复太短或是模板回复，基于用户论点生成引导性回复
                response_text = self._generate_guided_response(
                    user_argument, 
                    round_number, 
                    user_level,
                    question_content,
                    question_options
                )
            
            return {
                "response_text": response_text,
                "role": ai_role,
                "round": round_number,
                "suggestions": self._extract_suggestions(response_text),
                "timestamp": datetime.now().isoformat()
            }
        except Exception as e:
            print(f"生成AI回应失败: {e}")
            return {
                "response_text": "请继续完善你的论证，从法律条文和事实两个角度深入分析。",
                "role": ai_role,
                "round": round_number,
                "suggestions": ["加强法律条文的引用", "完善事实分析"],
                "timestamp": datetime.now().isoformat(),
                "error": str(e)
            }
    
    def _format_key_facts(self, key_facts: List[Dict[str, Any]]) -> str:
        """格式化关键事实"""
        if not key_facts:
            return "  无"
        facts_text = []
        for i, fact in enumerate(key_facts[:3], 1):
            fact_text = fact.get("fact", "") if isinstance(fact, dict) else str(fact)
            facts_text.append(f"  {i}. {fact_text[:50]}")
        return "\n".join(facts_text)
    
    def _format_legal_entities(self, entities: List[Dict[str, Any]]) -> str:
        """格式化法律实体"""
        if not entities:
            return "  无"
        entities_text = []
        for i, entity in enumerate(entities[:3], 1):
            if isinstance(entity, dict):
                entity_name = entity.get("name", entity.get("text", ""))
                entity_type = entity.get("type", "")
                entities_text.append(f"  {i}. {entity_name} ({entity_type})")
            else:
                entities_text.append(f"  {i}. {entity}")
        return "\n".join(entities_text)
    
    def _format_reasoning_chain(self, reasoning_chain: Dict[str, Any]) -> str:
        """格式化推理链条"""
        if not reasoning_chain:
            return "  无"
        completeness = reasoning_chain.get("reasoning_completeness", {})
        level = completeness.get("level", "未知")
        score = completeness.get("score", 0)
        return f"  完整性等级：{level}（{score}分）"
    
    def _generate_guided_response(
        self,
        user_argument: str,
        round_number: int,
        user_level: str,
        question_content: str,
        question_options: Optional[List[str]] = None
    ) -> str:
        """
        生成引导性回复（当LLM返回模板回复时使用）
        基于用户的具体论点生成引导性回复
        """
        # 提取用户论点的关键词
        user_keywords = []
        if "意思一致" in user_argument or "意思表示" in user_argument:
            user_keywords.append("意思表示一致")
        if "成立合同" in user_argument or "合同成立" in user_argument:
            user_keywords.append("合同成立")
        if "约定" in user_argument:
            user_keywords.append("约定")
        
        if user_level == "beginner":
            # 初学者引导性回复
            response = "【我的思考】\n"
            response += f"我理解你的想法。你提到"
            if "意思一致" in user_argument:
                response += "'意思一致就成立合同'，这个想法很有道理。"
            elif "约定" in user_argument:
                response += "'当下的约定就成立么'，这是个很好的问题。"
            else:
                response += "你的观点，让我来分析一下。"
            
            response += "\n\n【我的引导性质疑】\n"
            response += "我们可以从另一个角度思考：\n"
            response += "1. 从事实角度：除了意思一致，合同成立还需要什么条件呢？比如，双方是否都有行为能力？合同内容是否合法？\n"
            response += "2. 从逻辑角度：如果只要意思一致就成立合同，那么口头承诺是否也算合同？这在实际生活中会有什么问题？\n"
            response += "3. 从常识角度：一般生活中，我们签订合同会注意什么？为什么要有书面合同？\n"
            
            response += "\n【我的建议】\n"
            response += "建议你继续思考：\n"
            response += "- 可以再想想这个案例中，除了意思一致，还有哪些关键信息？\n"
            response += "- 如果换一个角度，比如从合同生效的要件来思考，会得出什么结论？\n"
            if round_number >= 2:
                response += "- 可以了解一下《民法典》中关于合同成立的规定，看看法律是怎么说的。\n"
        else:
            # 进阶者引导性回复
            response = "【我的思考】\n"
            response += f"让我分析一下你的论点。你提到"
            if "意思一致" in user_argument:
                response += "'意思一致就成立合同'，这个观点涉及合同成立的要件问题。"
            else:
                response += "你的观点，让我从法律角度分析。"
            
            response += "\n\n【我的质疑】\n"
            response += "我认为你的论证可以从以下方面完善：\n"
            response += "1. 合同成立的要件：根据《民法典》相关规定，合同成立需要意思表示一致，但还需要其他要件。\n"
            response += "2. 意思表示的形式：意思表示可以通过书面、口头等形式，但不同形式的法律效果可能不同。\n"
            response += "3. 合同生效与成立的区别：合同成立不等于合同生效，需要区分这两个概念。\n"
            
            response += "\n【我的建议】\n"
            response += "建议你从以下角度完善论证：\n"
            response += "- 明确合同成立的要件（意思表示一致、标的确定等）\n"
            response += "- 分析题目中的具体情况是否符合这些要件\n"
            response += "- 引用相关法条支持你的观点\n"
        
        return response
    
    def _detect_user_level(self, user_id: str) -> str:
        """
        检测用户水平（用于调整引导方式）
        
        Returns:
            "beginner": 初学者（非法学背景，准确率低）
            "intermediate": 中级（有一定基础）
            "advanced": 高级（法学背景或准确率高）
        """
        try:
            from app.services.user_level_service import user_level_service
            
            # 获取用户水平信息
            level_info = user_level_service.get_user_level(user_id)
            current_difficulty = level_info.get("current_difficulty", "easy")
            accuracy_by_difficulty = level_info.get("accuracy_by_difficulty", {})
            
            # 计算总体准确率
            total_questions = 0
            total_correct = 0
            for difficulty, accuracy in accuracy_by_difficulty.items():
                # 从准确率反推题目数量（估算）
                if accuracy > 0:
                    # 假设至少做了10道题才有意义
                    total_questions += 10
                    total_correct += int(accuracy * 10 / 100)
            
            overall_accuracy = (total_correct / total_questions * 100) if total_questions > 0 else 0
            
            # 判断用户水平
            if total_questions < 10:
                # 题目太少，默认为初学者
                return "beginner"
            elif overall_accuracy < 50 or current_difficulty == "easy":
                # 准确率低或只做简单题，可能是初学者
                return "beginner"
            elif overall_accuracy >= 70 and current_difficulty in ["hard", "medium"]:
                # 准确率高且能做中高难度题，可能是进阶者
                return "advanced"
            else:
                # 中等水平
                return "intermediate"
                
        except Exception as e:
            print(f"检测用户水平失败: {e}")
            # 默认返回初学者，更安全
            return "beginner"
    
    async def _evaluate_debate(self, debate_session: Dict[str, Any]) -> Dict[str, Any]:
        """评估辩论质量"""
        rounds = debate_session.get("rounds", [])
        if not rounds:
            return {
                "argument_quality": 0,
                "logical_rigor": 0,
                "legal_accuracy": 0,
                "improvement_suggestions": ["请提交至少一轮论点"],
                "summary": "辩论未开始"
            }
        
        # 分析所有轮次的论点
        all_arguments = [r["user_argument"] for r in rounds]
        combined_argument = "\n".join(all_arguments)
        
        # 使用Legal-BERT分析
        key_facts = await self.legalbert.extract_key_facts(combined_argument)
        entities = await self.legalbert.extract_entities(combined_argument)
        reasoning_chain = await self.legalbert.extract_legal_reasoning_chain(
            debate_session["question_content"],
            combined_argument
        )
        
        # 计算评分
        reasoning_completeness = reasoning_chain.get("reasoning_completeness", {})
        completeness_score = reasoning_completeness.get("score", 0)
        
        # 法律实体数量
        legal_provisions = [e for e in entities if e["type"] == "法律条文"]
        legal_accuracy = min(100, len(legal_provisions) * 20 + completeness_score // 2)
        
        # 逻辑严谨性（基于推理链条完整性）
        logical_rigor = completeness_score
        
        # 论证质量（综合评分）
        argument_quality = (legal_accuracy + logical_rigor + completeness_score) // 3
        
        # 生成改进建议
        suggestions = []
        if completeness_score < 66:
            suggestions.append("推理链条不完整，建议补充大前提（法律条文）或小前提（关键事实）")
        if len(legal_provisions) == 0:
            suggestions.append("缺少法律条文的引用，建议明确相关法条")
        if len(key_facts) < 2:
            suggestions.append("关键事实提取不足，建议更详细地分析案例事实")
        if logical_rigor < 70:
            suggestions.append("逻辑推理需要加强，建议使用三段论推理方法")
        
        return {
            "argument_quality": argument_quality,
            "logical_rigor": logical_rigor,
            "legal_accuracy": legal_accuracy,
            "reasoning_completeness": completeness_score,
            "key_facts_count": len(key_facts),
            "legal_provisions_count": len(legal_provisions),
            "total_rounds": len(rounds),
            "improvement_suggestions": suggestions if suggestions else ["论证质量良好，继续保持"],
            "summary": self._generate_evaluation_summary(argument_quality, logical_rigor, legal_accuracy),
            "evaluated_at": datetime.now().isoformat()
        }
    
    def _generate_evaluation_summary(
        self,
        argument_quality: int,
        logical_rigor: int,
        legal_accuracy: int
    ) -> str:
        """生成评估总结"""
        if argument_quality >= 80:
            return "论证质量优秀，逻辑严谨，法律适用准确"
        elif argument_quality >= 60:
            return "论证质量良好，仍有改进空间"
        else:
            return "论证需要进一步完善，建议加强法律条文理解和逻辑推理训练"
    
    def _extract_suggestions(self, text: str) -> List[str]:
        """从文本中提取建议"""
        suggestions = []
        if "建议" in text:
            suggestions.append("参考系统建议完善论证")
        if "注意" in text:
            suggestions.append("注意关键点")
        if "加强" in text:
            suggestions.append("加强相关方面的训练")
        return suggestions if suggestions else []
    
    async def _get_debate_session(self, debate_id: str) -> Optional[Dict[str, Any]]:
        """获取辩论会话"""
        if self.redis:
            try:
                key = f"debate:{debate_id}"
                data = self.redis.get(key)
                if data:
                    return json.loads(data)
            except Exception as e:
                print(f"获取辩论会话失败: {e}")
        return None
    
    async def _save_debate_session(self, debate_id: str, session: Dict[str, Any]):
        """保存辩论会话"""
        if self.redis:
            try:
                key = f"debate:{debate_id}"
                self.redis.setex(
                    key,
                    86400 * 7,  # 保存7天
                    json.dumps(session, ensure_ascii=False)
                )
            except Exception as e:
                print(f"保存辩论会话失败: {e}")


# 单例实例
debate_service = DebateService()


